iT邦幫忙

2023 iThome 鐵人賽

DAY 11
0
Mobile Development

Android Studio 30天進階學習系列 第 11

Android Studio 30天進階學習-DAY11_使用Kotlin基礎語法建立一個簡易計算機

  • 分享至 

  • xImage
  •  

前面兩天提到了基本Kotlin的語法及一些進階用法,今天就要利用這些基礎與法來建立基礎專案,對於剛接觸Kotlin語法又想要建立一份Android專案的學習者,這篇就稍微利用了幾個基本套件來建立一個"簡易計算機

  • 使用到的Android Studio內建基礎XML布置文件
    • Button
    • TextView
    • GuildLine
    • Toolbar
  • Kotlin撰寫功能
    • Button跳轉頁面功能
    • Button以及TextView建立按鈕輸入輸出顯示
    • 建立類別(Class)來處理計算功能。

所以今天主要還是著重在Kotlin的語法撰寫練習,來熟悉如何撰寫功能類別。
對於布置文件中的套件不熟的人可以去看看我之前所寫的IT鐵人賽文章,當中有詳細介紹。

簡易計算機

  • Calculator.kt
class Calculator {
    private var currentInput: String = ""
    private var currentOperator: String = ""
    private var operand1: Double = 0.0
    private var operand2: Double = 0.0

    // 加入小數點
    fun appendDigit(digit: String) {
        currentInput += digit
    }

    // 加入數字
    fun appendDigit(digit: Int) {
        currentInput += digit.toString()
    }

    // 將+-*/的文字傳入並將其設置
    fun setOperator(operator: String) {
        if (currentInput.isNotEmpty()) {
            currentOperator = operator
            operand1 = currentInput.toDouble()
            currentInput = ""
        }
    }

    // 計算_方法函式
    fun calculate(): Any {
        if (currentInput.isNotEmpty() && currentOperator.isNotEmpty()) {
            operand2 = currentInput.toDouble()
            val result = when (currentOperator) {
                "+" -> operand1 + operand2
                "-" -> operand1 - operand2
                "*" -> operand1 * operand2
                "/" -> {
                    if (operand2 != 0.0) {
                        operand1 / operand2
                    } else {
                        // Handle division by zero
                        return Double.NaN
                    }
                }
                else -> return Double.NaN
            }

            // 清除當前輸入
            currentInput = ""

            // 根據小數點的長度判斷是否使用科學符號
            val resultString = if (result.isNaN() || !result.isFinite()) {
                "Error"
            } else {
                val resultFormatted = if (result % 1 == 0.0) {
                    result.toInt().toString()
                } else {
                    val resultStr = result.toString()
                    if (resultStr.length > 8) {
                        String.format("%.3e", result)
                    } else {
                        resultStr
                    }
                }
                resultFormatted
            }

            return resultString
        }
        return Double.NaN
    }

    fun getCurrentInput(): String {
        return currentInput
    }

    // 清除function
    fun clear() {
        currentInput = ""
        currentOperator = ""
        operand1 = 0.0
        operand2 = 0.0
    }
}
  • 計算機頁面程式碼
class CalculatorMachine : AppCompatActivity() {
    
    // 引入Calculator方法類別,並將其設為延遲初始化的變數。
    private lateinit var calculator: Calculator
    
    override fun onCreate(savedInstanceState: Bundle?) {
        // ..原本的程式碼省略

        calculator = Calculator()

        // 使用一般方法一個一個引入XML布置文件的物件
        val resultTextView = findViewById<TextView>(R.id.resultTextView)

        val button0 = findViewById<Button>(R.id.button0)
        val button1 = findViewById<Button>(R.id.button1)
        val button2 = findViewById<Button>(R.id.button2)
        val button3 = findViewById<Button>(R.id.button3)
        val button4 = findViewById<Button>(R.id.button4)
        val button5 = findViewById<Button>(R.id.button5)
        val button6 = findViewById<Button>(R.id.button6)
        val button7 = findViewById<Button>(R.id.button7)
        val button8 = findViewById<Button>(R.id.button8)
        val button9 = findViewById<Button>(R.id.button9)

        // 加減乘除按鈕
        val buttonAdd = findViewById<Button>(R.id.buttonAdd)
        val buttonSubtract = findViewById<Button>(R.id.buttonSubtract)
        val buttonMultiply = findViewById<Button>(R.id.buttonMultiply)
        val buttonDivide = findViewById<Button>(R.id.buttonDivide)
        val buttonDecimal = findViewById<Button>(R.id.buttonDecimal)
        val buttonEquals = findViewById<Button>(R.id.buttonEquals)

        // 將0~9數字鍵整合成一個陣列。
        val digitButtons = listOf(button0, button1, button2, button3, button4, button5, button6, button7, button8, button9)

        // 建立清除以及返回主頁面的按鈕
        val buttonClear = findViewById<Button>(R.id.buttonClear)
        val buttonBack = findViewById<Button>(R.id.buttonBack)
    
        // 清除輸入字
        buttonClear.setOnClickListener {
            calculator.clear() // 調用 calculator 的清除方法
            resultTextView.text = calculator.getCurrentInput()
        }

        // 返回主頁面
        buttonBack.setOnClickListener{
            val intent = Intent(this, MainActivity::class.java)
            startActivity(intent)
        }

        // 設置數字按鈕的點擊事件
        digitButtons.forEachIndexed { index, button ->
            button.setOnClickListener {
                calculator.appendDigit(index)
                resultTextView.text = calculator.getCurrentInput()
            }
        }

        // 設置運算符號按鈕的點擊事件
        buttonAdd.setOnClickListener {
            calculator.setOperator("+")
        }

        buttonSubtract.setOnClickListener {
            calculator.setOperator("-")
        }

        buttonMultiply.setOnClickListener {
            calculator.setOperator("*")
        }

        buttonDivide.setOnClickListener {
            calculator.setOperator("/")
        }

        // 設置等於按鈕的點擊事件
        buttonEquals.setOnClickListener {
            val result = calculator.calculate()
            resultTextView.text = result.toString()
        }

        // 設置小數點按鈕的點擊事件
        buttonDecimal.setOnClickListener {
            calculator.appendDigit(".")
            resultTextView.text = calculator.getCurrentInput()
        }
    }
}
  • 主頁面跳轉程式碼
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {

        val button = findViewById<Button>(R.id.calculateButton)
        button.setOnClickListener {
            val intent = Intent(this, CalculatorMachine::class.java)
            startActivity(intent)
        }
    }
}

XML畫面布置文件

  • 計算機畫面XML布置文件
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        android:padding="16dp">

        <TextView
            android:id="@+id/resultTextView"
            android:layout_width="match_parent"
            android:layout_height="120dp"
            android:layout_marginTop="35dp"
            android:text="0"
            android:gravity="end"
            android:textSize="72dp"/>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_marginTop="15dp">

            <Button
                android:id="@+id/button7"
                android:layout_width="0dp"
                android:layout_height="100dp"
                android:layout_weight="1"
                android:text="7"
                android:textSize="28dp"/>

            <Button
                android:id="@+id/button8"
                android:layout_width="0dp"
                android:layout_height="100dp"
                android:layout_weight="1"
                android:text="8"
                android:textSize="28dp"/>

            <Button
                android:id="@+id/button9"
                android:layout_width="0dp"
                android:layout_height="100dp"
                android:layout_weight="1"
                android:text="9"
                android:textSize="28dp"/>

            <Button
                android:id="@+id/buttonDivide"
                android:layout_width="0dp"
                android:layout_height="100dp"
                android:layout_weight="1"
                android:text="/"
                android:textSize="28dp"/>
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_marginTop="16dp">

            <Button
                android:id="@+id/button4"
                android:layout_width="0dp"
                android:layout_height="100dp"
                android:layout_weight="1"
                android:text="4"
                android:textSize="28dp"/>

            <Button
                android:id="@+id/button5"
                android:layout_width="0dp"
                android:layout_height="100dp"
                android:layout_weight="1"
                android:text="5"
                android:textSize="28dp"/>

            <Button
                android:id="@+id/button6"
                android:layout_width="0dp"
                android:layout_height="100dp"
                android:layout_weight="1"
                android:text="6"
                android:textSize="28dp"/>

            <Button
                android:id="@+id/buttonMultiply"
                android:layout_width="0dp"
                android:layout_height="100dp"
                android:layout_weight="1"
                android:text="*"
                android:textSize="28dp"/>
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_marginTop="16dp">

            <Button
                android:id="@+id/button1"
                android:layout_width="0dp"
                android:layout_height="100dp"
                android:layout_weight="1"
                android:text="1"
                android:textSize="28dp"/>

            <Button
                android:id="@+id/button2"
                android:layout_width="0dp"
                android:layout_height="100dp"
                android:layout_weight="1"
                android:text="2"
                android:textSize="28dp"/>

            <Button
                android:id="@+id/button3"
                android:layout_width="0dp"
                android:layout_height="100dp"
                android:layout_weight="1"
                android:text="3"
                android:textSize="28dp"
                />

            <Button
                android:id="@+id/buttonSubtract"
                android:layout_width="0dp"
                android:layout_height="100dp"
                android:layout_weight="1"
                android:text="-"
                android:textSize="28dp"/>
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_marginTop="16dp">

            <Button
                android:id="@+id/button0"
                android:layout_width="0dp"
                android:layout_height="100dp"
                android:layout_weight="1"
                android:text="0"
                android:textSize="28dp"/>

            <Button
                android:id="@+id/buttonDecimal"
                android:layout_width="0dp"
                android:layout_height="100dp"
                android:layout_weight="1"
                android:text="."
                android:textSize="28dp"/>

            <Button
                android:id="@+id/buttonEquals"
                android:layout_width="0dp"
                android:layout_height="100dp"
                android:layout_weight="1"
                android:text="="
                android:textSize="28dp"/>

            <Button
                android:id="@+id/buttonAdd"
                android:layout_width="0dp"
                android:layout_height="100dp"
                android:layout_weight="1"
                android:text="+"
                android:textSize="28dp"/>
        </LinearLayout>
        <LinearLayout
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:orientation="horizontal"
            android:layout_gravity="center"
            android:layout_marginTop="15dp">
            <Button
                android:id="@+id/buttonClear"
                android:layout_width="wrap_content"
                android:layout_height="50dp"
                android:text="Clear"
                android:textSize="20dp"/>
            <Button
                android:id="@+id/buttonBack"
                android:layout_width="wrap_content"
                android:layout_height="50dp"
                android:text="Back"
                android:textSize="20dp"/>
        </LinearLayout>
    </LinearLayout>
  • 布置圖預覽如下
    https://ithelp.ithome.com.tw/upload/images/20230921/20150370AOKQUR1ijj.png

  • MainActivity布置文件

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline_horizontal_1_percent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        app:layout_constraintGuide_percent="0.1"
        android:orientation="horizontal"/>

    <Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:background="@color/black"
        app:layout_constraintBottom_toTopOf="@+id/guideline_horizontal_1_percent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="IT_Home鐵人賽_Kotlin簡易小專案"
        android:textColor="@color/white"
        android:textSize="25dp"
        app:layout_constraintBottom_toTopOf="@+id/guideline_horizontal_1_percent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/toolbar" />

    <Button
        android:id="@+id/calculateButton"
        android:layout_width="wrap_content"
        android:layout_height="100dp"
        android:text="計算機"
        android:textSize="25dp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/guideline_horizontal_1_percent" />

  • 預覽檢視圖
    https://ithelp.ithome.com.tw/upload/images/20230921/20150370r95VXfY8YC.png

結果操作

這邊操作900+100,因為只有功能是完整的畫面顯示的部分還沒做到如今小算盤的那麼周全,所以只展示最後按下 "="按鈕後的計算結果,以及小數點過長顯示的數字變換成科學記號顯示,如:100/7

  • 900+100
    https://ithelp.ithome.com.tw/upload/images/20230921/20150370qZKcnwluRy.png
  • 100/7
    https://ithelp.ithome.com.tw/upload/images/20230921/201503701b0z4R7wav.png

上一篇
Android Studio 30天進階學習-DAY10_Kotlin處理工具(KAPT & KSP)概述
下一篇
Android Studio 30天進階學習-DAY12_使用Kotlin撰寫接取API小專案
系列文
Android Studio 30天進階學習30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言